home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
afloat.zip
/
FMULT.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-03-15
|
3KB
|
148 lines
PAGE ,132
;----------------------------------------------------------
; FMULT -- version for use with assembly-language programs
;
; Copyright Bob Kline 1988
;
; Purpose:
; Multiply two single-precision floating-point numbers.
;
; Input:
; DX:AX contain multiplicand in single-precision IEEE
; format; CX:BX contain multiplier, same format.
;
; Output:
; Product (IEEE) single-precision real in DX:AX.
;
; Other registers used:
; Values changed in BP, SI, DI, BX, CX
;
; Procedures called:
; None.
;
; Comments:
; Sets variable _errno to ERANGE if overflow
; occurs. If a calling routine will be testing
; _errno, it must first reset the variable to
; zero to be sure that an error code is not
; left over from some previous call.
;----------------------------------------------------------
.MODEL SMALL
PUBLIC FMULT
EXTRN _errno:WORD
EXPONENT EQU BP
ERANGE EQU 34
.CODE
FMULT PROC
; get sign of result and save it
MOV SI,DX
XOR DX,CX
AND DX,8000h
PUSH DX
MOV DX,SI
; add exponents, save result
MOV EXPONENT,CX
MOV DI,DX
SHL DX,1
SHL CX,1
XCHG DH,DL
XCHG CH,CL
XOR DH,DH
XOR CH,CH
SUB CX,127
SUB DX,127
ADD CX,DX
XCHG EXPONENT,CX
MOV DX,DI
; unpack mantissas
AND DX,7Fh
AND CX,7Fh
OR DX,80h
OR CX,80h
; multiply DX:AX by CX:BX; since only 24 bits each in multiplier
; and multiplicand, result will have 47 or 48 bits, so we would
; only need 3 registers for the result -- but we actually only
; need 2 since final mantissa can only use the most significant
; 24 bits. We will look at the 25th bit for rounding decision
; before throwing it away
PUSH DX
PUSH DX
PUSH AX
MUL BX ; A x B
MOV SI,DX
POP AX
MUL CX ; A x C
ADD SI,AX
MOV DI,DX
ADC DI,0
POP AX
MUL BX ; D x B
ADD SI,AX
ADC DI,DX
POP AX
MUL CX ; D x C
ADD DI,AX
MOV AX,SI
MOV DX,DI
; if result is 47 bits, shift it up into the 48th bit
JS L0
SHL AX,1
RCL DX,1
JMP SHORT L1
L0: INC EXPONENT
; quick 8-bit left shift
L1: XCHG AH,AL
XCHG DL,AH
XCHG DH,DL
; round up if necessary
TEST DH,80h
JZ L2
AND DX,0FFh
INC AX
JNC L2
INC DX
; and adjust exponent if we rounded all the way through the top bit
TEST DH,1
JZ L2
INC EXPONENT
; make the top bit invisible
L2: AND DX,7Fh
; get the exponent back
MOV BX,EXPONENT
ADD BX,127
; check to make sure the exponent isn't out of range
OR BH,BH
JZ L3
MOV _errno,ERANGE
XOR BH,BH
; get back into position for packing and fold it in
L3: XCHG BH,BL
SHR BX,1
OR DX,BX
; get the sign back and return
POP CX
OR DX,CX
RET
FMULT ENDP
END